package Models

import (
	"ali-hr/Database"
	"github.com/gookit/goutil/dump"
	"github.com/jinzhu/gorm"
	"strconv"
	"strings"
	"time"
)

/**
 * Created by Goland
 * User: wkk alisleepy@hotmail.com
 * Time: 2022/3/27 - 17:28
 * Desc: <部门Department模型>
 */

const (
	DepartmentTableName string = "ali_department"
	DepartmentClose     string = "封存"
	DepartmentEffect    string = "生效"
)

type Department struct {
	Id        uint        `gorm:"primary_key" json:"id"`
	Name      string      `json:"name"`
	ParentId  int         `json:"parent_id"`
	LeaderId  int         `json:"leader_id"`
	IdPath    string      `json:"id_path"`
	NamePath  string      `json:"name_path"`
	Level     string      `json:"level"`
	Status    string      `json:"status"`
	CompanyId int         `json:"company_id"`
	CreatedAt time.Time   `json:"created_at"`
	UpdatedAt time.Time   `json:"updated_at"`
	DeletedAt *time.Time  `json:"deleted_at;default:null"`
	Leader    *Staff      `gorm:"FOREIGNKEY:Id; ASSOCIATION_FOREIGNKEY:LeaderId" json:"leader"`   // 关联的部门负责人
	Parent    *Department `gorm:"FOREIGNKEY:Id; ASSOCIATION_FOREIGNKEY:ParentId" json:"parent"`   // 关联的父级部门信息，自己关联自己
	Company   *Company    `gorm:"FOREIGNKEY:Id; ASSOCIATION_FOREIGNKEY:CompanyId" json:"company"` // 关联的法人主体
}

// DepartmentTree 部门树
type DepartmentTree struct {
	Id       uint             `json:"id"`
	Name     string           `json:"label"`
	ParentId int              `json:"pid"`
	Children []DepartmentTree `json:"children"`
	Expand   bool             `json:"expand"` // 是否展开
}

// AfterCreate 定义钩子，创建部门后，自动更新部门id_path和level，name_path信息
func (department *Department) AfterCreate(db *gorm.DB) (err error) {
	// 父级部门ID为0，表示当前为1级部门
	if department.ParentId == 0 {
		department.IdPath = strconv.Itoa(int(department.Id))
		department.NamePath = department.Name
		department.Level = strconv.Itoa(getLevelByIdPath(department.IdPath))
		department.CreatedAt = time.Now()
		db.Save(&department)
		return nil
	}

	// 父级部门ID != 0,
	var parent Department
	err1 := Database.SqlDB.Where("id = ?", department.ParentId).Find(&parent).Error
	if err1 != nil {
		dump.P("父级部门获取失败， parent_id")
		return err1
	}
	department.IdPath = parent.IdPath + "-" + strconv.Itoa(int(department.Id))
	department.NamePath = parent.NamePath + "-" + department.Name
	department.Level = strconv.Itoa(getLevelByIdPath(department.IdPath))
	db.Save(&department)
	return nil
}

// AfterUpdate 更新部门钩子操作，在更新部门后，继续更新当前部门的子部门数据
func (department *Department) AfterUpdate(db *gorm.DB) (err error) {
	var children []Department
	err = Database.SqlDB.Where("parent_id = ? and status != ?", department.Id, DepartmentClose).Find(&children).Error
	if err != nil {
		dump.P("获取子部门失败，无需更新，部门ID = ", department.Id)
		return nil
	}
	if len(children) == 0 {
		return nil
	}
	// 2、修改子部门的level，id_path, name_path
	for _, child := range children {
		child.IdPath = department.IdPath + "-" + strconv.Itoa(int(child.Id))
		child.NamePath = department.NamePath + "-" + child.Name
		child.Level = strconv.Itoa(getLevelByIdPath(child.IdPath))
		child.UpdatedAt = time.Now()
		Database.SqlDB.Save(child)
	}
	return nil
}

// getLevelByIdPath 根据idPath 获取 部门level
func getLevelByIdPath(idPath string) int {
	return len(strings.Split(idPath, "-"))
}
